<template>
  <CDialog
    :title="dataInfo?.relationNo ? '关联关系修改' : '关联关系新增'"
    v-model:visible="dialogVisible"
    @confirm="handleConfirm"
    @cancel="dialogVisible = false"
    :loading="loading"
  >
    <el-form
      class="factor-table"
      ref="formRef"
      :model="taskForm"
      :rules="rules"
      label-position="top"
    >
      <el-row :gutter="8">
        <el-col :span="24">
          <el-form-item label="目录" prop="frameworkNo">
            <el-cascader
              popper-class="cascader-wrap"
              v-model="taskForm.frameworkNo"
              :options="treeDataList"
              :props="cascaderProps"
              filterable
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="排放源：" prop="sourceNo">
            <el-cascader
              v-model="taskForm.sourceNo"
              :options="sourceOptions"
              filterable
              :props="cascaderProps1"
              value-key="index"
            />
          </el-form-item>
        </el-col>
        <el-col :span="16">
          <el-form-item label="能源/燃料" prop="materialNo">
            <GSelect
              placeholder="请选择"
              v-model="taskForm.materialNo"
              filterable
              class="header-select--remote"
              @change="getUnitListByFactor"
              @visible-change="handleVisibleChange"
            >
              <el-option
                v-for="item in selectOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </GSelect>
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="" class="g-mt26" prop="dataUnit">
            <GSelect placeholder="能源/燃料单位" v-model="taskForm.dataUnit">
              <el-option v-for="item in unitOptions" :key="item" :label="item" :value="item" />
            </GSelect>
          </el-form-item>
        </el-col>
      </el-row>
      <p class="g-font-14n1b g-mt16 g-mb16">因子关联</p>
      <CTable :data-source="dataSource" useDataSource :pagination="false" border>
        <vxe-column title="因子标准" width="140">
          <template #default="scope">
            {{ scope.row.name }}
          </template>
        </vxe-column>
        <vxe-column title="是否适用" width="100">
          <template #default="scope">
            <GSelect v-model="scope.row.suit">
              <el-option label="适用" value="YES" />
              <el-option label="不适用" value="NO" />
            </GSelect>
          </template>
        </vxe-column>
        <vxe-column title="关联因子">
          <template #default="scope">
            <span v-if="scope.row.suit == 'NO'">无需关联</span>
            <div class="g-flex-between-center" v-else-if="scope.row.factorName">
              <p v-ellTooltip>{{ scope.row.factorName }}</p>
              <el-button type="primary" text @click="handleRelation(scope.row)">重新关联</el-button>
            </div>
            <div class="g-flex-between-center" v-else>
              <p style="color: #96a7b3">待关联</p>
              <el-button type="primary" text @click="handleRelation(scope.row)">前往关联</el-button>
            </div>
          </template>
        </vxe-column>
      </CTable>
    </el-form>
    <CFactorDialog
      v-model:visible="showFactorDialog"
      :taskForm="taskForm"
      :selectRow="selectRow"
      @finish="handleFinish"
    ></CFactorDialog>
  </CDialog>
</template>
<script lang="ts">
export default {
  name: 'RelationshipDialog'
};
</script>
<script lang="ts" setup>
import { defineProps, withDefaults, defineEmits, computed, ref, watch, reactive } from 'vue';
import { CDialog } from '@/components/CDialog/index';
import { rules } from './rules';
import { useMessage } from '@/hooks/useMessage';
import { CTable } from '@/components/CTable/index';
import { GSelect } from '@/components/GSelect/index';
import CFactorDialog from '@/businessComponents/CFactorDialog/index.vue';
import { emissionTypeEnum, CarbonInventoryStandardsMap } from '@/constants/enum';
import { getEmissionOptions, addRelation, updateRelation } from '@/apis/system/config/relationship';
import { useRelation } from './useRelation';
import { cloneDeep } from 'lodash';

interface SelectFillTypeDialogProps {
  visible: boolean;
  dataInfo: any;
  treeData: any;
}
const cascaderProps = {
  emitPath: false,
  expandTrigger: 'hover',
  label: 'frameworkName',
  value: 'frameworkNo',
  children: 'childNodeList'
};
const cascaderProps1 = {
  emitPath: false
};
const props = withDefaults(defineProps<SelectFillTypeDialogProps>(), {
  dataInfo: () => ({}),
  treeData: () => ({})
});
const emit = defineEmits(['update:visible', 'refresh']);
const taskForm = reactive({
  frameworkNo: '',
  sourceNo: '',
  materialNo: '',
  materialName: '',
  dataUnit: ''
});
const {
  showFactorDialog,
  remoteMethod,
  selectOptions,
  getUnitListByFactor,
  unitOptions,
  handleVisibleChange,
  loadMaterialListDrop
} = useRelation(taskForm);

const dialogVisible = computed<boolean>({
  get: () => {
    return props.visible;
  },
  set: val => {
    emit('update:visible', val);
  }
});
watch(
  () => dialogVisible.value,
  visible => {
    if (!visible) {
      init();
    } else {
      initData();
    }
  }
);
const dataSource = ref([
  {
    name: CarbonInventoryStandardsMap.ISO,
    standard: 'ISO',
    suit: 'YES',
    factorName: '',
    factorNo: ''
  },
  {
    name: CarbonInventoryStandardsMap.GB,
    standard: 'GB',
    suit: 'YES',
    factorName: '',
    factorNo: ''
  },
  {
    name: CarbonInventoryStandardsMap.GHG,
    standard: 'GHG',
    suit: 'YES',
    factorName: '',
    factorNo: ''
  }
]);
const formRef = ref();
const loading = ref(false);
const sourceOptions = ref<any[]>([]);
const { createMessage } = useMessage();

const treeDataList = ref<any[]>([]);
const resetTreeData = (arr: any[]) => {
  // 重组tree
  let newArr = cloneDeep(arr);
  for (let i = 0; i < newArr.length; i++) {
    if (newArr[i].childNodeList) {
      newArr[i].childNodeList = resetTreeData(newArr[i].childNodeList);
    } else {
      newArr = newArr.filter(item => item.status == 'ENABLE'); // 只过滤启用的
    }
  }
  return newArr;
};
const initData = async () => {
  // 加载目录tree
  treeDataList.value = resetTreeData(
    props.treeData.frameworkName == '目录' ? props.treeData.childNodeList : [props.treeData]
  );
  if (!props.treeData.childNodeList) {
    //如果末级节点目录自动填充
    taskForm.frameworkNo = props.treeData.frameworkNo;
  }
  await getSourceOptions();
  props.dataInfo?.relationNo && loadData();
};
const getSourceOptions = () => {
  getEmissionOptions()
    .then(res => {
      sourceOptions.value = res.map(item => {
        const children = item.emissionSource.map(ite => {
          return {
            label: ite.name,
            value: ite.sourceNo
          };
        });
        return {
          label: emissionTypeEnum[item.type],
          value: item.type,
          children
        };
      });
      Promise.resolve();
    })
    .catch(() => {
      Promise.reject();
    });
};
const loadData = () => {
  taskForm.frameworkNo = props.dataInfo.frameworkNo;
  taskForm.sourceNo = props.dataInfo.sourceNo;
  loadMaterialListDrop().then(() => {
    taskForm.materialNo = props.dataInfo.materialNo;
    taskForm.materialName = props.dataInfo.materialName;
  });
  taskForm.dataUnit = props.dataInfo.dataUnit;
  dataSource.value = props.dataInfo.factorList.map((item: any) => {
    return {
      name: CarbonInventoryStandardsMap[item.standard as 'ISO' | 'GB' | 'GHG'],
      standard: item.standard,
      suit: item.factorNo == '-1' ? 'NO' : 'YES',
      factorName: item.factorName,
      factorNo: item.factorNo
    };
  });
};
const checkFactorList = () => {
  const length = dataSource.value.length;
  for (let i = 0; i < length; i++) {
    if (dataSource.value[i].suit == 'YES' && !dataSource.value[i].factorName) {
      createMessage.warning('请先关联因子！');
      return false;
    }
  }
  return true;
};
function handleConfirm() {
  formRef.value?.validate(async (valid: boolean, val: any) => {
    if (valid && checkFactorList()) {
      loading.value = true;
      const factorList = dataSource.value.map(item => {
        return {
          standard: item.standard,
          factorNo: item.suit == 'YES' ? item.factorNo : '-1'
        };
      });
      try {
        let params: any = {
          frameworkNo: taskForm.frameworkNo,
          sourceNo: taskForm.sourceNo,
          materialNo: taskForm.materialNo,
          dataUnit: taskForm.dataUnit,
          factorList
        };
        if (props.dataInfo?.relationNo) {
          params.relationNo = props.dataInfo?.relationNo;
          await updateRelation(params);
        } else {
          await addRelation(params);
        }
        createMessage.success(
          props.dataInfo?.relationNo ? '修改关联关系成功！' : '添加关联关系成功！'
        );
        dialogVisible.value = false;
        emit('refresh');
        init();
      } finally {
        loading.value = false;
      }
    } else {
      // 滚动到验证不通过的item上
      let keys = Object.keys(val);
      formRef.value?.scrollToField(keys[0]);
    }
  });
}
const selectRow = ref({});
const handleRelation = (row: any) => {
  formRef.value?.validate(async (valid: boolean, val: any) => {
    if (valid) {
      showFactorDialog.value = true;
      selectRow.value = row;
    }
  });
};
const handleFinish = (row: any) => {
  const index = dataSource.value.findIndex(n => n.name == row.name);
  dataSource.value[index].factorName = row.factorName;
  dataSource.value[index].factorNo = row.factorNo;
};
function init() {
  // 初始化数据
  loading.value = false;
  taskForm.frameworkNo = '';
  taskForm.sourceNo = '';
  taskForm.materialNo = '';
  taskForm.materialName = '';
  taskForm.dataUnit = '';
  dataSource.value = [
    {
      name: CarbonInventoryStandardsMap.ISO,
      standard: 'ISO',
      suit: 'YES',
      factorName: '',
      factorNo: ''
    },
    {
      name: CarbonInventoryStandardsMap.GB,
      standard: 'GB',
      suit: 'YES',
      factorName: '',
      factorNo: ''
    },
    {
      name: CarbonInventoryStandardsMap.GHG,
      standard: 'GHG',
      suit: 'YES',
      factorName: '',
      factorNo: ''
    }
  ];
  formRef.value?.resetFields();
}
</script>
<style lang="scss" scoped>
:deep(.el-form-item) {
  .el-cascader,
  .el-autocomplete,
  .el-select {
    width: 100%;
  }
}
.factor-table {
  :deep(.vxe-body--column) {
    position: relative;
    padding: 8px 0 !important;
    height: 44px;
    .el-select {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      .el-input__wrapper {
        height: 43px;
        border-radius: 0;
      }
    }
  }
}
</style>

<style lang="scss">
.cascader-wrap {
  .el-cascader-menu {
    min-width: 227px !important;
  }
}
</style>
